package org.iwidget.desktop.ui;
import org.iwidget.desktop.model.ElementTextField;
import org.iwidget.desktop.model.WidgetElement;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import javax.swing.JComponent;
/**
 *
 * @author Muhammad Hakim A
 */

public class WidgetText extends JComponent
    implements MouseListener, MouseMotionListener, KeyListener, DropTargetListener
{

    public WidgetText(WidgetElement widget, ElementTextField textData)
    {
        this.widget = widget;
        this.textData = textData;
        textData.setUIComponent(this);
        if(textData.getWidth() == 0)
            textData.setWidth(textData.calculateTextWidth());
        if(textData.getHeight() == 0)
            textData.setHeight(textData.calculateTextHeight());
        setSize(textData.getWidth(), textData.getHeight());
        setLocation(textData.getX(), textData.getY());
        setDoubleBuffered(true);
        setFocusable(true);
        setVisible(true);
        addMouseListener(this);
        addMouseMotionListener(this);
        addKeyListener(this);
    }

    public void initializeDrop()
    {
        DropTarget dropTarget = new DropTarget(this, this);
    }

    public void update(Graphics g)
    {
        paint(g);
    }

    public Color getColorObject()
    {
        if(textData.getColor().startsWith("#") && textData.getColor().length() == 7)
        {
            int intColor = Integer.decode(textData.getColor()).intValue();
            Color c = new Color(intColor, true);
            float masterOpacity = (float)textData.widget.getWindowJS().getOpacity() / 100F;
            masterOpacity *= (float)textData.getOpacity() / 100F;
            return new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(255F * masterOpacity));
        } else
        {
            return Color.BLACK;
        }
    }

    public Color getBGColorObject()
    {
        if(textData.getBgColor().startsWith("#") && textData.getBgColor().length() == 7)
        {
            int intColor = Integer.decode(textData.getBgColor()).intValue();
            Color c = new Color(intColor, true);
            float masterOpacity = (float)textData.widget.getWindowJS().getOpacity() / 100F;
            masterOpacity *= (float)textData.getBgOpacity() / 100F;
            return new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(255F * masterOpacity));
        } else
        {
            return Color.WHITE;
        }
    }

    public void paintComponent(Graphics g)
    {
        if(!textData.getVisible())
            return;
        Graphics2D g2 = (Graphics2D)g;
        if(textData.getTooltip() != null && textData.getTooltip().length() > 0)
            setToolTipText(textData.getTooltip());
        if(textData.getCursorObject() != null)
            setCursor(textData.getCursorObject());
        setBackground(getBGColorObject());
        if(textData.getAlignment().equals(ElementTextField.ALIGN_CENTER))
            setLocation(textData.getX() - textData.calculateTextWidth() / 2, textData.getY());
        else
        if(textData.getAlignment().equals(ElementTextField.ALIGN_RIGHT))
            setLocation(textData.getX() - textData.calculateTextWidth(), textData.getY());
        else
            setLocation(textData.getX(), textData.getY());
        g2.setColor(getColorObject());
        g2.setFont(textData.getFontObject());
        Hashtable map = new Hashtable();
        map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.addRenderingHints(map);
        FontMetrics fm = textData.getFontMetrics();
        g2.rotate(Math.toRadians(textData.getRotation()), (double)textData.getWidth() / 2D, (double)textData.getHeight() / 2D);
        g2.drawString(textData.getData(), textData.getScrollPosition(), textData.getHeight() - fm.getDescent());
    }

    public void mousePressed(MouseEvent e)
    {
        if(e.getButton() != 3)
        {
            textData.triggerEvent("onMouseDown");
            widget.getUIComponent().mousePressed(e);
        }
    }

    public void mouseReleased(MouseEvent e)
    {
        if(e.getButton() != 3)
        {
            textData.triggerEvent("onMouseUp");
            widget.getUIComponent().mouseReleased(e);
        } else
        {
            widget.getUIComponent().showContextMenu();
        }
    }

    public void mouseEntered(MouseEvent e)
    {
        if(widget.getAction("onKeyDown") != null || widget.getAction("onKeyUp") != null || widget.getAction("onKeyPress") != null)
            grabFocus();
        textData.triggerEvent("onMouseEnter");
    }

    public void mouseExited(MouseEvent e)
    {
        textData.triggerEvent("onMouseExit");
    }

    public void mouseMoved(MouseEvent mouseevent)
    {
    }

    public void mouseClicked(MouseEvent mouseevent)
    {
    }

    public void mouseDragged(MouseEvent e)
    {
        widget.getUIComponent().mouseDragged(e);
    }

    public void keyTyped(KeyEvent e)
    {
        textData.triggerEvent("onKeyPress");
        widget.triggerEvent("onKeyPress");
    }

    public void keyPressed(KeyEvent e)
    {
        widget.getIwidgetData().key = e.getKeyChar();
        widget.getIwidgetData().keyString = KeyEvent.getKeyText(e.getKeyCode());
        widget.getIwidgetData().keyModifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
        textData.triggerEvent("onKeyDown");
        widget.triggerEvent("onKeyDown");
    }

    public void keyReleased(KeyEvent e)
    {
        widget.getIwidgetData().key = e.getKeyChar();
        widget.getIwidgetData().keyString = KeyEvent.getKeyText(e.getKeyCode());
        widget.getIwidgetData().keyModifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
        textData.triggerEvent("onKeyUp");
        widget.triggerEvent("onKeyUp");
    }

    public void dragOver(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dragActionChanged(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dropActionChanged(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dragEnter(DropTargetDragEvent e)
    {
        textData.triggerEvent("onDragEnter");
    }

    public void dragExit(DropTargetEvent e)
    {
        textData.triggerEvent("onDragExit");
    }

    public void drop(DropTargetDropEvent e)
    {
        try
        {
            Transferable tr = e.getTransferable();
            if(tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
            {
                e.acceptDrop(3);
                ArrayList dropFiles = new ArrayList();
                ArrayList dropDirs = new ArrayList();
                java.util.List fileList = (java.util.List)tr.getTransferData(DataFlavor.javaFileListFlavor);
                for(Iterator iterator = fileList.iterator(); iterator.hasNext();)
                {
                    File file = (File)iterator.next();
                    if(file.isDirectory())
                        dropDirs.add(file.getAbsolutePath());
                    else
                        dropFiles.add(file.getAbsolutePath());
                }

                e.getDropTargetContext().dropComplete(true);
                String dropFilesArray[] = new String[dropFiles.size()];
                for(int iCtr = 0; iCtr < dropFiles.size(); iCtr++)
                    dropFilesArray[iCtr] = (String)dropFiles.get(iCtr);

                widget.getIwidgetData().droppedObjects = dropFilesArray;
                widget.getIwidgetData().droppedObjectsType = "filenames";
                textData.triggerEvent("onDragDrop");
            } else
            if(tr.isDataFlavorSupported(DataFlavor.stringFlavor))
            {
                e.acceptDrop(3);
                String url = (String)tr.getTransferData(DataFlavor.stringFlavor);
                if(url.toLowerCase().startsWith("http:") || url.toLowerCase().startsWith("https:") || url.toLowerCase().startsWith("ftp:"))
                {
                    String dropUrl[] = {
                        url
                    };
                    widget.getIwidgetData().droppedObjects = dropUrl;
                    widget.getIwidgetData().droppedObjectsType = "url";
                    e.getDropTargetContext().dropComplete(true);
                    textData.triggerEvent("onDragDrop");
                } else
                {
                    e.rejectDrop();
                }
            } else
            {
                System.err.println("Rejected");
                e.rejectDrop();
            }
        }
        catch(IOException io)
        {
            io.printStackTrace();
            e.rejectDrop();
        }
        catch(UnsupportedFlavorException ufe)
        {
            ufe.printStackTrace();
            e.rejectDrop();
        }
    }

    private static final long serialVersionUID = 0x2d37353835323839L;
    private WidgetElement widget;
    private ElementTextField textData;
}